package com.loveprogrammer.lowercode.dna.service.impl;

import com.loveprogrammer.lowercode.common.ReturnMessage;
import com.loveprogrammer.lowercode.dna.common.CodeDefConst;
import com.loveprogrammer.lowercode.dna.common.CommonInfo;
import com.loveprogrammer.lowercode.dna.common.OperationFlagEnum;
import com.loveprogrammer.lowercode.dna.def.Dna;
import com.loveprogrammer.lowercode.dna.def.DnaTool;
import com.loveprogrammer.lowercode.dna.instance.bo.Cell;
import com.loveprogrammer.lowercode.dna.instance.bo.Inst;
import com.loveprogrammer.lowercode.dna.service.DnaCacheService;
import com.loveprogrammer.lowercode.dna.service.InstDMService;
import com.loveprogrammer.lowercode.dna.service.InstService;
import com.loveprogrammer.lowercode.dna.util.InstVisitor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @ClassName InstServiceImpl
 * @Description
 * @Author admin
 * @Date 2024/5/31 15:10
 * @Version 1.0
 */
@Service
public class InstServiceImpl implements InstService {

    @Autowired
    private DnaCacheService dnaCacheService;

    @Autowired
    private InstDMService instDMService;

    @Override
    public Inst initInst(CommonInfo commonInfo, String businessType, String dnaCode) {

        Dna dna = dnaCacheService.getDna(businessType, dnaCode);
        Inst inst = new Inst(CodeDefConst.INST_TYPE_DEFAULT,dna,null);

        Cell cell = DnaTool.dna2Cell(CodeDefConst.INST_TYPE_DEFAULT, dna);
        inst.addCell(cell);
        return inst;
    }

    @Override
    public Inst saveInst(CommonInfo commonInfo, Inst inst) {
        InstVisitor.visitInst(inst, (Inst localinst) -> {
            if(localinst.getDna() == null) {
                Dna dna = dnaCacheService.getDna(localinst.getBusinessType(),localinst.getDnaCode());
                localinst.setDna(dna);
            }
        });
        return instDMService.saveInst(commonInfo, inst);
    }

    @Override
    public ReturnMessage<Inst> getInst(CommonInfo commonInfo, String businessType, String dnaCode, Object cellKey) {
        Dna dna = dnaCacheService.getDna(businessType, dnaCode);
        if(dna == null) {
            throw new RuntimeException("找不到Dna， businessType =" + businessType + ",dnaCode =" + dnaCode);
        }
        ReturnMessage<Inst> instResult = this.instDMService.getInst(commonInfo,dna,cellKey);
        if(instResult.isSuccess()){
            InstVisitor.visitInst(instResult.getData(),(Inst localInst) -> {
                for (Cell cell : localInst.getCells()) {
                    cell.setOperationFlag(OperationFlagEnum.UNCHANGED.getCode());
                }
            });
        }

        return instResult;
    }

    /***
     * 删除实例及其下的子孙节点，因为实例是一棵树形结构，当某个节点被删除时，所有孩子节点必须被删除 因此这是一个递归的过程
     * 从最末级叶子开始向上逐级删除，一直删除到参数cellKey所对应的实例为止。
     * @param commonInfo
     * @param businessType
     * @param dnaCode
     * @param cellKey 是实例值的键值 通过Dna上的dbMapCode可以定位到数据库表映射对象，它包含实例保存在哪些表中的信息，根据它可以从表中删除实例
     *
     * @return
     */
    @Override
    public ReturnMessage<Object> deleteInst(CommonInfo commonInfo,
                                            String businessType,
                                            String dnaCode,
                                            Object cellKey) {

        Dna dna = this.dnaCacheService.getDna(businessType, dnaCode);
        instDMService.deleteInst(commonInfo,dna,cellKey);
        return ReturnMessage.ok(cellKey);
    }


}
